/*
PearReview - The peer review assistant.
Copyright (C) 2009  Dimitrij Pankratz, Anton Musichin
http://www.pearreview.com, info@pearreview.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package com.pearreview.application;

import java.awt.BorderLayout;
import java.awt.Desktop;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.Serializable;
import java.net.URI;
import java.util.Locale;

import javax.swing.AbstractAction;
import javax.swing.GroupLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.border.EmptyBorder;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;

import com.pearreview.ui.EscapeDialog;
import com.pearreview.ui.FormLabel;
import com.pearreview.ui.PearPanel;

/**
 * Shows an information box for auto update.
 *
 */
public class UpdateBox extends EscapeDialog implements HyperlinkListener {
	private static final long serialVersionUID = -2109609140937636527L;
	
	public static final String LINK = 
			"http://www.pearreview.com/download.php?language=" + 
			Locale.getDefault().getLanguage();
	
	public static final int HISTORY_TEXT_HEIGHT = 100;
	
	private JPanel panel;
	private FormLabel currentVersionLabel;
	private FormLabel newVersionLabel;
	private JTextPane historyText;
	private JScrollPane historyTextScrollPane;
	private JButton showHideButton;
	
	public UpdateBox(Frame owner) {
		super(owner, true);
		initComponents();
	}

	public UpdateBox(Dialog owner) {
		super(owner, true);
		initComponents();
	}
	
	private void initComponents() {
		setFont(new Font("Tahoma", Font.PLAIN, 12));
		
		setTitle(getLocalizedString("title"));
		
		panel = new PearPanel();
		FormLabel descriptionCaption = new FormLabel();
		FormLabel currentVersionCaption = new FormLabel();
		FormLabel newVersionCaption = new FormLabel();
		currentVersionLabel = new FormLabel();
		newVersionLabel = new FormLabel();
		historyTextScrollPane = new JScrollPane();
		historyText = new JTextPane();
		historyText.setContentType("text/html");
		showHideButton = new JButton();
		JButton downloadLink = new JButton();
		
		//======== descriptionCaption ========
		descriptionCaption.setText(getLocalizedString("description"));
		descriptionCaption.setFont(getFont().deriveFont(Font.BOLD));

		//---- currentVersionCaption ----
		currentVersionCaption.setText(getLocalizedString("version.current"));
		

		//---- newVersionCaption ----
		newVersionCaption.setText(getLocalizedString("version.new"));

		//---- currentVersionLabel ----
		currentVersionLabel.setText(PearReview.VERSION.toString());
		
		//---- downloadLink ----
		downloadLink.setText(getLocalizedString("download"));
		downloadLink.setFont(getFont());
		downloadLink.setIcon(getResourceIcon("download_btn.png"));
		downloadLink.addActionListener(new DownloadActionListener());
		downloadLink.setOpaque(false);
		
		//======== historyText ========
		historyText.setEditable(false);
		historyText.setFont(getFont());
		historyText.setOpaque(false);
		
		//======== scrollPane1 ========
		{
			historyTextScrollPane.setBorder(new EmptyBorder(0, 0, 0, 0));
			historyTextScrollPane.getViewport().setOpaque(false);
			historyTextScrollPane.setOpaque(false);
			historyTextScrollPane.setViewportView(historyText);
			historyTextScrollPane.setVisible(false);
		}

		//---- showHideButton ----
		showHideButton.setAction(new HistoryAction());
		showHideButton.setFont(getFont());
		
		GroupLayout layout = new GroupLayout(panel);
		panel.setLayout(layout);
		layout.setHorizontalGroup(
				layout.createParallelGroup()
					.addGroup(layout.createSequentialGroup()
						.addContainerGap()
						.addGroup(layout.createParallelGroup()
							.addComponent(descriptionCaption)
							.addGroup(layout.createSequentialGroup()
								.addGroup(layout.createParallelGroup()
									.addComponent(currentVersionCaption)
									.addComponent(newVersionCaption))
								.addGap(20, 20, 20)
								.addGroup(layout.createParallelGroup()
									.addGroup(layout.createSequentialGroup()
										.addComponent(currentVersionLabel))
									.addComponent(newVersionLabel)))
							.addComponent(downloadLink, 
												GroupLayout.DEFAULT_SIZE, 
												GroupLayout.PREFERRED_SIZE, 
												Short.MAX_VALUE)
							.addComponent(showHideButton)
							.addComponent(historyTextScrollPane))
						.addContainerGap())
		);
		layout.setVerticalGroup(
			layout.createSequentialGroup()
				.addContainerGap()
				.addComponent(descriptionCaption)
				.addGap(20)
				.addContainerGap()
				.addGroup(layout.createParallelGroup(
						GroupLayout.Alignment.BASELINE)
					.addComponent(currentVersionCaption)
					.addComponent(currentVersionLabel))
				.addContainerGap()
				.addGroup(layout.createParallelGroup(
						GroupLayout.Alignment.BASELINE)
					.addComponent(newVersionCaption)
					.addComponent(newVersionLabel))
				.addContainerGap()
				.addGap(20)
				.addComponent(downloadLink)
				.addGap(30)
				.addComponent(showHideButton)
				.addGap(20)
				.addComponent(historyTextScrollPane)
				.addContainerGap()
		);
		
		getContentPane().add(panel, BorderLayout.CENTER);
		
		pack();
		
		setLocationRelativeTo(getOwner());
		
		setPreferredSize(getSize());
		setMinimumSize(getSize());
		setMaximumSize(new Dimension(Integer.MAX_VALUE, getSize().height));
		
		addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent e) {
				if(getHeight() > getMaximumSize().height && 
						getMaximumSize().height != Integer.MAX_VALUE ) {
					setSize(getSize().width, getMaximumSize().height);
				}
			}
		});
	}

	
	/**
	 * Returns localized string of this component
	 * @param key key of string to localize
	 * @return localized string of this component
	 */
	private static String getLocalizedString(String key) {
		return Messages.getString("PearReview.update." + key);
	}
	
	public void setVersion(Version version) {
		newVersionLabel.setText(version.toString());
	}
	
	public void setHistory(String history) {
		history = history.replaceAll("(\r\n|\r|\n|\n\r)", "<br />");
		historyText.setText("<html>" + history + "</html>");
		historyText.setCaretPosition(0);
	}
	
	private class HistoryAction extends AbstractAction {
		private static final long serialVersionUID = -4240345841182853921L;
		public HistoryAction() {
			invers();
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			historyTextScrollPane.setVisible(
					!historyTextScrollPane.isVisible());
			
			invers();
			
			int height = getMinimumSize().height;
			height += HISTORY_TEXT_HEIGHT * 
					(historyTextScrollPane.isVisible() ? 1 : -1);
			setMinimumSize(new Dimension(getMinimumSize().width, height));
			setSize(getSize().width, height);
			
			int maxHeight = historyTextScrollPane.isVisible() ? 
					Integer.MAX_VALUE : height;
			setMaximumSize(new Dimension(Integer.MAX_VALUE, maxHeight));
		}
		private void invers() {
			String str = "history." + 
					(historyTextScrollPane.isVisible() ? "hide" : "show");
			putValue(NAME, getLocalizedString(str));
		}
	}
	
	/**
	 * Returns a resource icon
	 * @param name name of icon
	 * @return
	 */
	private ImageIcon getResourceIcon(String name) {
		return new ImageIcon(getClass().getResource("images/" + name));
	}
	
	@Override
	public void hyperlinkUpdate(HyperlinkEvent e) {
		 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
			try {
				Desktop.getDesktop().browse(e.getURL().toURI());
			} catch(Exception ignore) {
			}
		}
	}
	
	private class DownloadActionListener implements 
			ActionListener, Serializable {
		private static final long serialVersionUID = -5460048854002865910L;
		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				Desktop.getDesktop().browse(new URI(LINK));
				dispose();
			} catch(Exception e1) {
				
			}
		}
	}
}
